package com.orange.entity.sprite.vbo;

import com.orange.entity.sprite.Sprite;
import com.orange.entity.sprite.TexturePackSprite;
import com.orange.entity.sprite.TiledSprite;
import com.orange.opengl.texture.region.ITextureRegion;
import com.orange.opengl.texture.region.ITiledTextureRegion;
import com.orange.opengl.vbo.DrawType;
import com.orange.opengl.vbo.VertexBufferObjectManager;
import com.orange.opengl.vbo.attribute.VertexBufferObjectAttributes;
import com.orange.util.texturepack.ITexturePackTextureRegion;
import com.orange.util.texturepack.ITiledTexturePackTextureRegion;
import com.orange.util.texturepack.TexturePackTextureRegion;

/**
 * 
 * 
 * @author  
 * @since 18:39:06 - 28.03.2012
 */
public class HighPerformanceTexturePackSpriteVertexBufferObject extends HighPerformanceTiledSpriteVertexBufferObject implements ITexturePackTiledSpriteVertexBufferObject {

	public HighPerformanceTexturePackSpriteVertexBufferObject(VertexBufferObjectManager pVertexBufferObjectManager, int pCapacity, DrawType pDrawType, boolean pAutoDispose, VertexBufferObjectAttributes pVertexBufferObjectAttributes) {
		super(pVertexBufferObjectManager, pCapacity, pDrawType, pAutoDispose, pVertexBufferObjectAttributes);
		// TODO Auto-generated constructor stub
	}

	
	public void onUpdateVertices(final TexturePackSprite pTexturePackSprite) {
		final float[] bufferData = this.mBufferData;

		ITiledTexturePackTextureRegion tiledTexturePackTextureRegion = pTexturePackSprite.getTiledTextureRegion();
		float spriteWidth = pTexturePackSprite.getWidth();
		float spriteHeight = pTexturePackSprite.getHeight();

		float x = 0;
		float y = 0;
		float x2 = spriteWidth; // TODO Optimize with field access?
		float y2 = spriteHeight; // TODO Optimize with field access?

		final int tileCount = pTexturePackSprite.getTileCount();
		int bufferDataOffset = 0;
		for (int i = 0; i < tileCount; i++) {
			ITexturePackTextureRegion texturePackTextureRegion = tiledTexturePackTextureRegion.getTextureRegion(i);
			float sourceX = texturePackTextureRegion.getSourceX();
			float sourceY = texturePackTextureRegion.getSourceY();
			float sourceWidth = texturePackTextureRegion.getSourceWidth();
			float sourceHeight = texturePackTextureRegion.getSourceHeight();
			float regionWidth = texturePackTextureRegion.getWidth();
			float regionHeight = texturePackTextureRegion.getHeight();
			x = sourceX;
			x2 = x + regionWidth;
			y = sourceY;
			y2 = y + regionHeight;
			if (pTexturePackSprite.isFlippedHorizontal()) {
				x = sourceWidth - x - regionWidth;
				x2 = x + regionWidth;
			}
			if (pTexturePackSprite.isFlippedVertical()) {
				y = sourceHeight - y - regionHeight;
				y2 = y + regionHeight;
			}
			if (sourceWidth != spriteWidth) {
				float scaleX = spriteWidth / sourceWidth;
				x = x * scaleX;
				x2 = x2 * scaleX;
			}
			if (sourceHeight != spriteHeight) {
				float scaleY = spriteHeight / sourceHeight;
				y = y * scaleY;
				y2 = y2 * scaleY;
			}

			bufferData[bufferDataOffset + 0 * TiledSprite.VERTEX_SIZE + Sprite.VERTEX_INDEX_X] = x;
			bufferData[bufferDataOffset + 0 * TiledSprite.VERTEX_SIZE + Sprite.VERTEX_INDEX_Y] = y;

			bufferData[bufferDataOffset + 1 * TiledSprite.VERTEX_SIZE + Sprite.VERTEX_INDEX_X] = x;
			bufferData[bufferDataOffset + 1 * TiledSprite.VERTEX_SIZE + Sprite.VERTEX_INDEX_Y] = y2;

			bufferData[bufferDataOffset + 2 * TiledSprite.VERTEX_SIZE + Sprite.VERTEX_INDEX_X] = x2;
			bufferData[bufferDataOffset + 2 * TiledSprite.VERTEX_SIZE + Sprite.VERTEX_INDEX_Y] = y;

			bufferData[bufferDataOffset + 3 * TiledSprite.VERTEX_SIZE + Sprite.VERTEX_INDEX_X] = x2;
			bufferData[bufferDataOffset + 3 * TiledSprite.VERTEX_SIZE + Sprite.VERTEX_INDEX_Y] = y;

			bufferData[bufferDataOffset + 4 * TiledSprite.VERTEX_SIZE + Sprite.VERTEX_INDEX_X] = x;
			bufferData[bufferDataOffset + 4 * TiledSprite.VERTEX_SIZE + Sprite.VERTEX_INDEX_Y] = y2;

			bufferData[bufferDataOffset + 5 * TiledSprite.VERTEX_SIZE + Sprite.VERTEX_INDEX_X] = x2;
			bufferData[bufferDataOffset + 5 * TiledSprite.VERTEX_SIZE + Sprite.VERTEX_INDEX_Y] = y2;

			bufferDataOffset += TiledSprite.TILEDSPRITE_SIZE;
		}

		this.setDirtyOnHardware();
	}

}